package com.company.gjtx.common.action;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.struts2.interceptor.SessionAware;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.company.gjtx.common.exception.BusinessException;
import com.company.gjtx.common.service.GenericManager;
import com.company.gjtx.common.util.AjaxBackData;
import com.company.gjtx.common.util.PageView;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;

public class GenericAction<T, ID extends Serializable> extends ActionSupport
		implements SessionAware, ModelDriven<T>, Preparable,
		ApplicationContextAware {

	private static final long serialVersionUID = 1L;

	protected Map session;

	protected static String NO_PERMIT = "noPermit";

	protected GenericManager<T, ID> manager;

	protected ApplicationContext applicationContext;

	/**
	 * 泛型 bean
	 */
	protected T instance;

	/**
	 * AJAX返回对象结果集
	 */
	protected AjaxBackData ajax;

	/**
	 * 当前T泛型的主键ID
	 */
	protected ID keyId;

	/**
	 * 当前T泛型的主键ID List
	 */
	protected String keyIdList;

	/**
	 * list集合
	 */
	protected List<T> result;

	/**
	 * 分页统计最大值
	 */
	protected int totalCount;

	/**
	 * 分页查询起始值
	 */
	protected Integer start;

	/**
	 * 分页查询最大值
	 */
	protected Integer limit;

	/***************************************************************************
	 * 分页查询封装对象
	 */
	protected PageView<T> page;

	/**
	 * 保存数据库
	 * 
	 * @param t：待保存的实体
	 *            返回ID
	 */
	protected String save(T t) {
		try {
			keyId = manager.save(t);
			dealSuccess("保存成功！");
		} catch (Exception e) {
			e.printStackTrace();
			dealException(e);
		}
		return SUCCESS;
	}

	/**
	 * 保存数据库
	 * 
	 * @param t：待保存的实体
	 */
	protected String saveOrUpdate(T t) {
		try {
			manager.saveOrUpdate(t);
			dealSuccess("保存成功！");
		} catch (Exception e) {
			e.printStackTrace();
			dealException(e);
		}
		return SUCCESS;
	}

	/**
	 * 批量保存数据库
	 * 
	 * @param list：待保存的实体集合
	 */
	protected String saveOrUpdateAll(List<T> list) {
		try {
			manager.saveOrUpdateAll(list);
			dealSuccess("批量保存成功！");
		} catch (Exception e) {
			e.printStackTrace();
			dealException(e);
		}
		return SUCCESS;
	}

	/**
	 * 修改数据
	 * 
	 * @param t：待修改的实体
	 */
	protected String modify(T t) {
		try {
			manager.modify(t);
			dealSuccess("修改成功！");
		} catch (BusinessException e) {
			e.printStackTrace();
			dealException(e);
		}
		return SUCCESS;
	}

	/**
	 * 删除单个数据
	 * 
	 * @param t：待删除的实体
	 */
	protected String delete(T t) {
		try {
			manager.remove(t);
			dealSuccess("删除成功！");
		} catch (BusinessException e) {
			e.printStackTrace();
			dealException(e);
		}
		return SUCCESS;
	}

	/**
	 * 删除数据
	 * 
	 * @param list:待删除的实体集合
	 */
	protected String deleteAll(List<T> list) {
		try {
			manager.removeAll(list);
			dealSuccess("批量删除成功！");
		} catch (BusinessException e) {
			e.printStackTrace();
			dealException(e);
		}
		return SUCCESS;
	}

	/**
	 * 根据条件分页查询
	 * 
	 * @param conditions:查询条件
	 * @param pageView:分页条件
	 */
	public PageView<T> findByPage(Map<String, Object> conditions,
			PageView<T> pageView) {
		try {
			return manager.findByPage(conditions, pageView);
		} catch (BusinessException e) {
			e.printStackTrace();
		}
		return new PageView();
	}

	/**
	 * 根据条件查询（不分页）
	 * 
	 * @param conditions:查询条件
	 * @param pageView:分页条件
	 */
	public List<T> find(Map<String, Object> conditions) {
		try {
			return manager.findByCondition(conditions);
		} catch (BusinessException e) {
			e.printStackTrace();
		}
		return new ArrayList();
	}

	/**
	 * <p>
	 * 通过ID查找
	 * </p>
	 * 
	 * @param id :
	 *            id
	 * @return 找到的实体
	 * @throws BusinessException
	 */
	public T findById(ID id) {
		try {
			return manager.findById(id);
		} catch (BusinessException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 封装异常信息
	 * 
	 * @param Exception
	 *            需要处理的异常信息 如果异常信息是BusinessException ，则将异常信息抛到界面，其他异常抛出异常名称及堆栈
	 */
	protected void dealException(Exception e) {
		if (e != null) {
			if (e instanceof BusinessException) {
				System.out.println(e.getLocalizedMessage());
				ajax = new AjaxBackData(false, e.getMessage());
			} else {
				ajax = new AjaxBackData(false, "异常信息: "
						+ e.getClass().getName());
			}
		}
	}

	/**
	 * 封装程序执行成功信息
	 * 
	 * @param msg
	 *            成功后需要返回的信息
	 */
	protected void dealSuccess(String msg) {
		if (msg != null && !msg.trim().equals("")) {
			ajax = new AjaxBackData(true, msg);
		} else {
			ajax = new AjaxBackData(true, SUCCESS);
		}
	}

	public void setSession(Map<String, Object> session) {
		this.session = session;
	}

	// protected boolean hasPermit(Long operationId) {
	// List l = (List) this.session.get(StaticData.SESSION_OPERATION_IDS);
	// if (l == null)
	// return false;
	// if (l.contains(operationId)) {
	// return true;
	// }
	// return false;
	// }

	public void prepare() throws Exception {
		this.instance = this.instanceAnnotationObject();

	}

	public T getModel() {
		return this.instance;
	}

	public T instanceAnnotationObject() throws Exception {
		Class<?> cl = this.getClass();
		Type[] types = ((ParameterizedType) cl.getGenericSuperclass())
				.getActualTypeArguments();
		try {
			return ((Class<T>) types[0]).newInstance();
		} catch (Exception e) {
			throw e;
		}
	}

	public void setApplicationContext(ApplicationContext arg0)
			throws BeansException {
		// TODO Auto-generated method stub
		this.applicationContext = arg0;
	}

	/**
	 * 格式化为UTF-8编码方式
	 * 
	 * @param str
	 * @return
	 */
	protected String decodeCNString(String str) {
		try {
			return java.net.URLDecoder.decode(str, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 将ISO-8859-1编码改为UTF-8
	 * 
	 * @param str
	 * @return
	 */
	protected String decodeCNStr(String str) {
		try {
			return new String(str.getBytes("ISO-8859-1"), "UTF-8");
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		return null;
	}

	protected Object managerGot(String beanname) {
		return this.applicationContext.getBean(beanname);
	}

	public T getInstance() {
		return instance;
	}

	public void setInstance(T instance) {
		this.instance = instance;
	}

	public AjaxBackData getAjax() {
		return ajax;
	}

	public void setAjax(AjaxBackData ajax) {
		this.ajax = ajax;
	}

	public GenericManager<T, ID> getManager() {
		return manager;
	}

	public void setManager(GenericManager<T, ID> manager) {
		this.manager = manager;
	}

	public List<T> getResult() {
		return result;
	}

	public void setResult(List<T> result) {
		this.result = result;
	}

	public ID getKeyId() {
		return keyId;
	}

	public void setKeyId(ID keyId) {
		this.keyId = keyId;
	}

	public String getKeyIdList() {
		return keyIdList;
	}

	public void setKeyIdList(String keyIdList) {
		this.keyIdList = keyIdList;
	}

	public Integer getStart() {
		return start;
	}

	public void setStart(Integer start) {
		this.start = start;
	}

	public Integer getLimit() {
		return limit;
	}

	public void setLimit(Integer limit) {
		this.limit = limit;
	}

	public PageView<T> getPage() {
		return page;
	}

	public void setPage(PageView<T> page) {
		this.page = page;
	}

	public int getTotalCount() {
		return totalCount;
	}

	public void setTotalCount(int totalCount) {
		this.totalCount = totalCount;
	}

}
